#ifndef __Singleton_hpp__
#define __Singleton_hpp__

#include "Exception.hpp"

namespace ge {

//----------------------------------------------------------------------------//
// Singleton< T > 
//----------------------------------------------------------------------------//

template < class T >
class Singleton
{
 public:
      
     Singleton( void )
     {
          geDebugAssertT( InvalidAction, instance == 0, "Singleton< T > - Instance Already Exists" );
          instance = static_cast< T* >( this );
     }

     ~Singleton( void )
     {
          instance = 0;
     }

     static bool HasInstance( void )
     {
          return instance != 0;
     }

     static T& Instance( void )
     {
          geDebugAssertT( FailedAccess, instance != 0, "Singleton< T > - No instance" );
          return *instance;
     }

     static T* InstancePtr( void )
     {
          geDebugAssertT( FailedAccess, instance != 0, "Singleton< T > - No instance" );
          return instance;
     }
     
 protected:

     static T* instance;

 private:

     Singleton( const Singleton& );
     Singleton& operator = ( const Singleton& );
};

template < class T >
T* Singleton< T >::instance = 0;

} // namespace ge

#endif//__Singleton_hpp__
